package core

import (
	"gitee.com/hongzhaomin/gspring/iface"
	"gitee.com/hongzhaomin/gspring/tools"
	"reflect"
)

func NewDefaultBeanDefinition(beanName string, refType reflect.Type) *DefaultBeanDefinition {
	tools.Assert().NotNil(refType, "refType must not be <nil>")

	refType = tools.ReflectTypeIndirect(refType)
	tools.Assert().IsTrue(refType.Kind() == reflect.Struct, "gspring bean kind must be struct")

	absBD := new(DefaultBeanDefinition)
	absBD.refType = refType
	if beanName != "" {
		absBD.beanName = beanName
	} else {
		absBD.beanName = tools.GetBeanName(refType.Name())
	}
	return absBD
}

//func NewDefaultBeanDefinitionByObj(bean any) *DefaultBeanDefinition {
//	tools.Assert().NotNil(bean, "gspring bean must not be <nil>")
//
//	rv := reflect.ValueOf(bean)
//
//	rvIndirect := reflect.Indirect(rv)
//	tools.Assert().IsTrue(rvIndirect.Kind() == reflect.Struct, "gspring bean kind must be struct")
//
//	absBD := new(DefaultBeanDefinition)
//	if rv.Kind() == reflect.Ptr {
//		tools.Assert().IsFalse(rv.IsNil(), "gspring bean must not be <nil>")
//		absBD.bean = bean
//	} else {
//		rvPtrNew := reflect.New(rvIndirect.Type())
//		rvPtrNew.Elem().Set(rv)
//		absBD.bean = rvPtrNew.Interface()
//	}
//
//	absBD.refType = rvIndirect.Type()
//	absBD.beanName = tools.GetBeanName(absBD.refType.Name())
//	return absBD
//}

// =====================================================================
// ======================= DefaultBeanDefinition =======================
// =====================================================================
var _ iface.BeanDefinition = (*DefaultBeanDefinition)(nil)

type DefaultBeanDefinition struct {
	beanName string // bean名称
	//bean     any          // bean原始对象
	refType reflect.Type // bean反射类型，非指针
}

func (my *DefaultBeanDefinition) GetParent() iface.BeanDefinition {
	return nil
}

func (my *DefaultBeanDefinition) SetParent(iface.BeanDefinition) iface.BeanDefinition {
	return my
}

func (my *DefaultBeanDefinition) GetBeanName() string {
	tools.Assert().NotBlank(my.beanName, "beanName is blank")
	return my.beanName
}

func (my *DefaultBeanDefinition) SetBeanName(beanName string) iface.BeanDefinition {
	tools.Assert().NotBlank(beanName, "beanName must not be blank")
	my.beanName = beanName
	return my
}

//func (my *DefaultBeanDefinition) GetObject() any {
//	return my.bean
//}

func (my *DefaultBeanDefinition) SetObjRefType(refType reflect.Type) iface.BeanDefinition {
	tools.Assert().NotNil(refType, "refType must not be <nil>")
	tools.Assert().IsTrue(refType.Kind() == reflect.Struct, "refType must be struct kind")
	//if my.refType != refType && my.bean != nil {
	//	my.bean = nil
	//}
	my.refType = refType
	return my
}

func (my *DefaultBeanDefinition) GetObjRefType() reflect.Type {
	tools.Assert().NotNil(my.refType, "refType is <nil>")
	return my.refType
}

func (my *DefaultBeanDefinition) GetObjRefTypeToPtr() reflect.Type {
	return reflect.PointerTo(my.GetObjRefType())
}

func (my *DefaultBeanDefinition) GetCreateBeanMethodInfo() *iface.CreateBeanMethodInfo {
	return nil
}

func (my *DefaultBeanDefinition) SetCreateBeanMethodInfo(*iface.CreateBeanMethodInfo) iface.BeanDefinition {
	return my
}
